home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / GNU_KIT / DISK8.ZIP / src / makest / expand.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-08  |  8.5 KB  |  340 lines

  1. /* Variable expansion functions for GNU Make.
  2. Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  3. This file is part of GNU Make.
  4.  
  5. GNU Make is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 1, or (at your option)
  8. any later version.
  9.  
  10. GNU Make is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with GNU Make; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "make.h"
  20. #include "commands.h"
  21. #include "file.h"
  22. #include "variable.h"
  23.  
  24.  
  25. /* Recursively expand V.  The returned string is malloc'd.  */
  26.  
  27. static char *
  28. recursively_expand (v)
  29.      register struct variable *v;
  30. {
  31.   char *value;
  32.  
  33.   if (v->expanding)
  34.     {
  35.       /* Expanding V causes infinite recursion.  Lose.  */
  36.       if (reading_filename == 0)
  37.     fatal ("Recursive variable `%s' references itself (eventually)",
  38.            v->name);
  39.       else
  40.     fatal ("%s:%u: Recursive variable `%s' references itself (eventually)",
  41.            reading_filename, *reading_lineno_ptr, v->name);
  42.     }
  43.  
  44.   v->expanding = 1;
  45.   value = allocated_variable_expand (v->value);
  46.   v->expanding = 0;
  47.  
  48.   return value;
  49. }
  50.  
  51. /* Scan LINE for variable references and expansion-function calls.
  52.    Build in `variable_buffer' the result of expanding the references and calls.
  53.    Return the address of the resulting string, which is null-terminated
  54.    and is valid only until the next time this function is called.  */
  55.  
  56. char *
  57. variable_expand (line)
  58.      register char *line;
  59. {
  60.   register struct variable *v;
  61.   register char *p, *o, *p1;
  62.  
  63.   p = line;
  64.   o = initialize_variable_output ();
  65.  
  66.   while (1)
  67.     {
  68.       /* Copy all following uninteresting chars all at once to the
  69.          variable output buffer, and skip them.  Uninteresting chars end
  70.      at the next $ or the end of the input.  */
  71.  
  72.       p1 = index (p, '$');
  73.  
  74.       o = variable_buffer_output (o, p, p1 != 0 ? p1 - p : strlen (p) + 1);
  75.  
  76.       if (p1 == 0)
  77.     break;
  78.       p = p1 + 1;
  79.  
  80.       /* Dispatch on the char that follows the $.  */
  81.  
  82.       switch (*p)
  83.     {
  84.     case '$':
  85.       /* $$ seen means output one $ to the variable output buffer.  */
  86.       o = variable_buffer_output (o, p, 1);
  87.       break;
  88.  
  89.     case '(':
  90.     case '{':
  91.       /* $(...) or ${...} is the general case of substitution.  */
  92.       {
  93.         char openparen = *p;
  94.         char closeparen = (openparen == '(') ? ')' : '}';
  95.         register char *beg = p + 1;
  96.         char *op, *begp;
  97.         char *end;
  98.  
  99.         op = o;
  100.         begp = p;
  101.         if (handle_function (&op, &begp))
  102.           {
  103.         o = op;
  104.         p = begp;
  105.         break;
  106.           }
  107.  
  108.         /* Is there a variable reference inside the parens or braces?
  109.            If so, expand it before expanding the entire reference.  */
  110.  
  111.         p1 = index (beg, closeparen);
  112.         if (p1 != 0)
  113.           p1 = lindex (beg, p1, '$');
  114.         if (p1 != 0)
  115.           {
  116.         /* BEG now points past the opening paren or brace.
  117.            Count parens or braces until it is matched.  */
  118.         int count = 0;
  119.         for (p = beg; *p != '\0'; ++p)
  120.           {
  121.             if (*p == openparen)
  122.               ++count;
  123.             else if (*p == closeparen && --count < 0)
  124.               break;
  125.           }
  126.         /* If count is >= 0, there were unmatched opening parens
  127.            or braces, so we go to the simple case of a variable name
  128.            such as `$($(a)'.  */
  129.         if (count < 0)
  130.           {
  131.             char *name = expand_argument (beg, p);
  132.             static char start[3] = { '$', }, end[2];
  133.             start[1] = openparen;
  134.             end[0] = closeparen;
  135.             p1 = concat (start, name, end);
  136.             free (name);
  137.             name = allocated_variable_expand (p1);
  138.             o = variable_buffer_output (o, name, strlen (name));
  139.             free (name);
  140.             break;
  141.           }
  142.           }
  143.  
  144.         /* This is not a reference to a built-in function and
  145.            it does not contain any variable references inside.
  146.            There are several things it could be.  */
  147.  
  148.         p = index (beg, ':');
  149.         if (p != 0 && lindex (beg, p, closeparen) == 0)
  150.           {
  151.         /* This is a substitution reference: $(FOO:A=B).  */
  152.         int count;
  153.         char *subst_beg, *replace_beg;
  154.         unsigned int subst_len, replace_len;
  155.  
  156.         v = lookup_variable (beg, p - beg);
  157.  
  158.         subst_beg = p + 1;
  159.         count = 0;
  160.         for (p = subst_beg; *p != '\0'; ++p)
  161.           {
  162.             if (*p == openparen)
  163.               ++count;
  164.             else if (*p == closeparen)
  165.               --count;
  166.             else if (*p == '=' && count <= 0)
  167.               break;
  168.           }
  169.         if (count > 0)
  170.           /* There were unmatched opening parens.  */
  171.           return initialize_variable_output ();
  172.         subst_len = p - subst_beg;
  173.  
  174.         replace_beg = p + 1;
  175.         count = 0;
  176.         for (p = replace_beg; *p != '\0'; ++p)
  177.           {
  178.             if (*p == openparen)
  179.               ++count;
  180.             else if (*p == closeparen && --count < 0)
  181.               break;
  182.           }
  183.         if (count > 0)
  184.           /* There were unmatched opening parens.  */
  185.           return initialize_variable_output ();
  186.         end = p;
  187.         replace_len = p - replace_beg;
  188.  
  189.         if (v != 0 && *v->value != '\0')
  190.           {
  191.             char *value = (v->recursive ? recursively_expand (v)
  192.                    : v->value);
  193.             if (lindex (subst_beg, subst_beg + subst_len, '%') != 0)
  194.               {
  195.             p = savestring (subst_beg, subst_len);
  196.             p1 = savestring (replace_beg, replace_len);
  197.             o = patsubst_expand (o, value, p, p1,
  198.                          index (p, '%'), index (p1, '%'));
  199.             free (p);
  200.             free (p1);
  201.               }
  202.             else
  203.               o = subst_expand (o, value, subst_beg, replace_beg,
  204.                     subst_len, replace_len, 0, 1);
  205.             if (v->recursive)
  206.               free (value);
  207.           }
  208.           }
  209.  
  210.         /* No, this must be an ordinary variable reference.  */
  211.         else
  212.           {
  213.         /* Look up the value of the variable.  */
  214.         end = index (beg, closeparen);
  215.         if (end == 0)
  216.           return initialize_variable_output ();
  217.         v = lookup_variable (beg, end - beg);
  218.  
  219.         if (v != 0 && *v->value != '\0')
  220.           {
  221.             char *value = (v->recursive ? recursively_expand (v)
  222.                    : v->value);
  223.             o = variable_buffer_output (o, value, strlen (value));
  224.             if (v->recursive)
  225.               free (value);
  226.           }
  227.           }
  228.  
  229.         /* Advance p past the variable reference to resume scan.  */
  230.         p = end;
  231.       }
  232.       break;
  233.  
  234.     case '\0':
  235.     case '\t':
  236.     case ' ':
  237.       break;
  238.  
  239.     default:
  240.       /* A $ followed by a random char is a variable reference:
  241.          $a is equivalent to $(a).  */
  242.       {
  243.         /* We could do the expanding here, but this way
  244.            avoids code repetition at a small performance cost.  */
  245.         char name[5];
  246.         name[0] = '$';
  247.         name[1] = '(';
  248.         name[2] = *p;
  249.         name[3] = ')';
  250.         name[4] = '\0';
  251.         p1 = allocated_variable_expand (name);
  252.         o = variable_buffer_output (o, p1, strlen (p1));
  253.         free (p1);
  254.       }
  255.  
  256.       break;
  257.     }      
  258.  
  259.       if (*p == '\0')
  260.     break;
  261.       else
  262.     ++p;
  263.     }
  264.  
  265.   (void) variable_buffer_output (o, "", 1);
  266.   return initialize_variable_output ();
  267. }
  268.  
  269. /* Expand an argument for an expansion function.
  270.    The text starting at STR and ending at END is variable-expanded
  271.    into a null-terminated string that is returned as the value.
  272.    This is done without clobbering `variable_buffer' or the current
  273.    variable-expansion that is in progress.  */
  274.  
  275. char *
  276. expand_argument (str, end)
  277.      char *str, *end;
  278. {
  279.   char *tmp = savestring (str, end - str);
  280.   char *value = allocated_variable_expand (tmp);
  281.  
  282.   free (tmp);
  283.  
  284.   return value;
  285. }
  286.  
  287. /* Expand LINE for FILE.  Error messages refer to the file and line where
  288.    FILE's commands were found.  Expansion uses FILE's variable set list.  */
  289.  
  290. char *
  291. variable_expand_for_file (line, file)
  292.      char *line;
  293.      register struct file *file;
  294. {
  295.   char *result;
  296.   struct variable_set_list *save;
  297.  
  298.   if (file == 0)
  299.     return variable_expand (line);
  300.  
  301.   save = current_variable_set_list;
  302.   current_variable_set_list = file->variables;
  303.   reading_filename = file->cmds->filename;
  304.   reading_lineno_ptr = &file->cmds->lineno;
  305.   result = variable_expand (line);
  306.   current_variable_set_list = save;
  307.   reading_filename = 0;
  308.   reading_lineno_ptr = 0;
  309.  
  310.   return result;
  311. }
  312.  
  313. /* Like variable_expand, but the returned string is malloc'd.  */
  314. char *
  315. allocated_variable_expand (line)
  316.      char *line;
  317. {
  318.   return allocated_variable_expand_for_file (line, (struct file *) 0);
  319. }
  320.  
  321. /* Like variable_expand_for_file, but the returned string is malloc'd.  */
  322.  
  323. char *
  324. allocated_variable_expand_for_file (line, file)
  325.      char *line;
  326.      struct file *file;
  327. {
  328.   char *save;
  329.   char *value;
  330.  
  331.   save = save_variable_output ();
  332.  
  333.   value = variable_expand_for_file (line, file);
  334.   value = savestring (value, strlen (value));
  335.  
  336.   restore_variable_output (save);
  337.  
  338.   return value;
  339. }
  340.